#include "bitmap.h"
#include "stdint.h"
#include "string.h"
#include "print.h"
#include "interrupt.h"
#include "debug.h"

//将位图初始化为0
void bitmap_init(struct bitmap* btmp){
    memset(btmp->bits, 0, btmp->btmp_bytes_len);
}

//判断bit_idx位是否为1，为1返回true
int bitmap_scan_test(struct bitmap* btmp, uint32_t bit_idx){
    uint32_t byte_idx = bit_idx / 8;//找的字节的位置
    uint32_t bit_odd = bit_idx % 8;//找到具体的位
    return (btmp->bits[byte_idx] & (BITMAP_MASK << bit_odd));
}

//在位图申请连续cnt个位，成功返回起始位下标，识别返回-1
int bitmap_scan(struct bitmap* btmp, uint32_t cnt){
    uint32_t idx_byte = 0;//记录空闲位所在字节
    while ((0xff == btmp->bits[idx_byte]) && (idx_byte < btmp->btmp_bytes_len)){
        //1表示已分配，0xff表示无空闲位
        idx_byte++;
    }
    ASSERT(idx_byte < btmp->btmp_bytes_len);
    if(idx_byte == btmp->btmp_bytes_len){
        //该内存池找不到空闲空间
        return -1;
    }
    int idx_bit = 0;
    while((uint8_t)(BITMAP_MASK << idx_bit) & btmp->bits[idx_byte]){
        //判断字节中位是否为1，返回空闲位索引
        idx_bit++;
    }

    //空闲位在位图中的下标
    int bit_idx_start = idx_byte * 8 + idx_bit;
    if(cnt == 1){
        //分配数为1直接返回
        return bit_idx_start;
    }
    uint32_t bit_left = (btmp->btmp_bytes_len * 8 - bit_idx_start);//记录可以寻找多少个空闲位
    uint32_t next_bit = bit_idx_start + 1;
    uint32_t connt = 1;//记录空闲位的个数

    bit_idx_start = -1;//找不到连续的空闲位直接返回-1
    while(bit_left-- > 0){
        /*在剩下的位图中找连续的空闲位*/
        if(!(bitmap_scan_test(btmp, next_bit))){
            connt++;
        } else {
            connt = 0;
        }
        if(connt == cnt){//寻找到了连续的空闲位
            bit_idx_start = next_bit - cnt + 1;
            break;
        }
        next_bit++;
    }
    return bit_idx_start;
}
//将位图的bit_idx位设为value
void bitmap_set(struct bitmap* btmp, uint32_t bit_idx, int8_t value){
    ASSERT((value == 0) || (value  == 1));
    uint32_t byte_idx = bit_idx / 8;
    uint32_t bit_odd = bit_idx % 8;

    if(value){
        btmp->bits[byte_idx] |= (BITMAP_MASK << bit_odd);
    } else {
        btmp->bits[bit_idx] &= ~(BITMAP_MASK << bit_odd);
    }
}




